// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2005-1-17

#ifndef __SCORE_WAR3MSG_H_SERVER_SVR_MAIN__
#define __SCORE_WAR3MSG_H_SERVER_SVR_MAIN__

#pragma once

namespace JoyServer
{
namespace ScoreWar3
{

enum Race
{
    Race_None   = 0x00,
    Race_Random = 0x60,
    Race_Human  = 0x41,
    Race_Orc    = 0x42,
    Race_Undead = 0x48,
    Race_Night  = 0x44,
};

enum Umpire
{
    Umpire_Group = 0x0C,
};

enum BackColor
{
    BackColor_Red    = 0x00,
	BackColor_Blue   = 0x01,
	BackColor_Aqua   = 0x02,
	BackColor_Indigo = 0x03,
	BackColor_Yellow = 0x04,
	BackColor_Orange = 0x05,
	BackColor_Reseda = 0x06,
	BackColor_Pink   = 0x07,
	BackColor_Gray   = 0x08,
	BackColor_Tint   = 0x09,
	BackColor_Green  = 0x0a,
	BackColor_Brown  = 0x0b,
};
enum Power
{
	Power_Percent100 = 0x64,
	Power_percent90  = 0x5a,
	Power_percent80  = 0x50,
	Power_percent70  = 0x46,
	Power_percent60  = 0x3c,
	Power_percent50  = 0x32,
};
enum BattleResult
{
    BR_None  = 0x00,
    BR_Test  = 0x1B,
    BR_Break = 0x01,

    BR_Exit = 0x07,
    BR_Loss = 0x08,
    BR_Win  = 0x09,
};

enum BattleMode
{
    BM_None = 0,
    BM_1v1  = 1,
    BM_2v2  = 2,
    BM_3v3  = 3,
    BM_4v4  = 4,
    BM_FFA  = 5,
};
enum BattleType
{
	BT_1v1   = 0x19,
	BT_FFA   = 0x22,
	BT_2v2   = 0x2B,
	BT_3v3   = 0x3D,
	BT_4v4   = 0x4F,
	BT_3v3v3 = 0x58,
	BT_6v6   = 0x73,
};

enum MessageId
{
#   define JOY_WAR3_MSG_DEF(type, value) MID_##type = value,
#   include "score_war3msgdef.h"
};

#define JOY_WAR3MSG_TEMPLATE(name) \
    template<int _TypeId, typename _SelfType>\
    struct MSG_##name : public MessageRoot<_TypeId, _SelfType>

#define JOY_WAR3MSG_T(name, baseClass) struct MSG_##name : public MSG_##baseClass<MID_##name, MSG_##name>
#define JOY_WAR3MSG(name) struct MSG_##name : public MessageRoot<MID_##name, MSG_##name>


#pragma pack(push, 1)

struct MessageBase
{
    WORD    m_type;
    WORD    m_size;
};

template<int _TypeId, typename _SelfType>
struct MessageRoot : public MessageBase
{
    enum MessageConstant
    {
        TypeId = _TypeId,
    };
    typedef _SelfType SelfType;

    bool IsValid() const
    {
        if(m_size < sizeof(SelfType) || m_type != TypeId)
        {
            return false;
        }
        return true;
    }
};

// not use this message in analyzer.
JOY_WAR3MSG(BattleResult)
{
	BYTE    m_unknown1;
	BYTE    m_unknown2;
	UINT    m_result;
    BYTE    m_unknown3[0x7A];
};

JOY_WAR3MSG(BattleCreate)
{
    BYTE  m_gameTag[4];
    DWORD m_unknown2; // always 11 00 00 00
    DWORD m_gameId; // times of creating game before a player exit the game
};

JOY_WAR3MSG(ExitBattle)
{
    UINT    m_code; // 09 win, 08 loss, 07 exit
};

JOY_WAR3MSG(ExitBattle2)
{
    BYTE    m_id;
    UINT    m_code; // 09 win, 08 loss, 07 exit
};

JOY_WAR3MSG(JoinBattle)
{
    UINT    m_gameId; //  times of creating game before a player exit the game 
    UINT    m_unknownId;
    BYTE    m_unknown;

    WORD    m_port;
	UINT    m_handle;		    // handle/descriptor for client <-> client communication
    CHAR    m_player_name[1];   // null terminated.
    UINT    m_unknown1;
	WORD    m_unknownId1;
	ULONG   m_ipAddress;
};

JOY_WAR3MSG_TEMPLATE(PlayerInfoBase)
{
    struct PlayerInfo
	{
		BYTE  m_id;
        BYTE  m_kindof; // 0x64: player; 0xFF:computer;
		BYTE  m_state;  //  00:open; 01:close; 02:in use;
	    BYTE  m_unknown;//  player: 0x00; computer: 0x01;
	    BYTE  m_group;
	    BYTE  m_backColor;
	    BYTE  m_race;
	    BYTE  m_grade; //computer  0x00: simple; 0x01:middle; 0x02:crazy  ;
	    BYTE  m_power;
	   
	};
    
	WORD  m_battleType; //1v1:0x19,FFA:0x22,2v2:0x2B,3v3:0x3D,4v4:0x4F,3v3v3:0x58,6v6:0x73 ;
	BYTE  m_count;
    PlayerInfo m_player[1];
    
	
   

    bool IsValid() const
    {
        if(!__super::IsValid())
        {
            return false;
        }
        if((int)((m_count-1)*sizeof(PlayerInfo)+sizeof(SelfType)) > (int)(m_size+2))
        {
            return false;
        }
        return true;
    }
};

JOY_WAR3MSG_T(PlayerList, PlayerInfoBase)
{
};

JOY_WAR3MSG_T(PlayerId, PlayerInfoBase)
{

};

JOY_WAR3MSG_TEMPLATE(EchoBase)
{
    UINT m_ticks;
};
JOY_WAR3MSG_T(EchoRequest, EchoBase)
{
};
JOY_WAR3MSG_T(EchoResponse, EchoBase)
{
};

JOY_WAR3MSG(FindBattle)
{
    BYTE    m_gameTag[4]; // 3WAR
    UINT    m_unknown1;   // always 11 00 00 00
    UINT    m_gameId; // times of creating game before a player exit the game 
};

JOY_WAR3MSG(StartBattle)
{
};

JOY_WAR3MSG(LoadBattle)
{
};

JOY_WAR3MSG(EndBattle)
{
};

JOY_WAR3MSG(MapPreview)
{
	UINT m_tag[4];
	CHAR m_name[1];
};

JOY_WAR3MSG(MapInfo)
{
    UINT    m_gameId; // tems of creating game before a player exit the game
    CHAR    m_name[1];    // null terminated.
 
};
JOY_WAR3MSG(Disconnection)
{
    BYTE    m_srcId;
	BYTE    m_DiscId;
};

JOY_WAR3MSG(NetFurbish)
{
    BYTE    m_id;
};

#pragma pack(pop)

} // namespace ScoreWar3
} // namespace JoyServer

#endif  // __SCORE_WAR3MSG_H_SERVER_SVR_MAIN__